import { Provide, Inject } from '@midwayjs/core';
import { BaseService } from '@cool-midway/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, In } from 'typeorm';
import { ProviderVisitLogEntity } from '../entity/visit_log';
import { UserInfoEntity } from '../../user/entity/info';
import { Context } from '@midwayjs/koa';

@Provide()
export class ProviderVisitLogService extends BaseService {
    @InjectEntityModel(ProviderVisitLogEntity)
    providerVisitLogEntity: Repository<ProviderVisitLogEntity>;

    @InjectEntityModel(UserInfoEntity)
    userInfoEntity: Repository<UserInfoEntity>;

    @Inject()
    ctx: Context;

    /**
     * 记录访问
     */
    async record(providerId: number, userId: number) {
        if (!userId || !providerId) return;
        await this.providerVisitLogEntity.save({
            providerId,
            userId,
        });
    }

    /**
     * 访问统计
     */
    async stats() {
        const providerId = this.ctx.provider.id;

        const overallList = await this.buildVisitRank(providerId);
        const totalVisits = overallList.reduce((sum, item) => sum + item.visitCount, 0);

        const now = Date.now();
        const weekRank = await this.buildVisitRank(providerId, new Date(now - 7 * 24 * 60 * 60 * 1000));
        const monthRank = await this.buildVisitRank(providerId, new Date(now - 30 * 24 * 60 * 60 * 1000));
        const yearRank = await this.buildVisitRank(providerId, new Date(now - 365 * 24 * 60 * 60 * 1000));

        return {
            totalVisitors: overallList.length,
            totalVisits,
            list: overallList,
            rank: {
                week: weekRank,
                month: monthRank,
                year: yearRank,
            },
        };
    }

    /**
     * 构建访问排行
     */
    private async buildVisitRank(providerId: number, startTime?: Date) {
        const query = this.providerVisitLogEntity
            .createQueryBuilder('log')
            .select('log.userId', 'userId')
            .addSelect('COUNT(1)', 'visitCount')
            .where('log.providerId = :providerId', { providerId });

        if (startTime) {
            query.andWhere('log.createTime >= :startTime', { startTime });
        }

        const raw = await query
            .groupBy('log.userId')
            .orderBy('visitCount', 'DESC')
            .getRawMany<{ userId: number; visitCount: string }>();

        const userIds = raw.map(v => Number(v.userId)).filter(id => !!id);
        let users: Pick<UserInfoEntity, 'id' | 'nickName' | 'avatarUrl'>[] = [];
        if (userIds.length) {
            users = await this.userInfoEntity.find({
                where: { id: In(userIds) },
                select: ['id', 'nickName', 'avatarUrl'],
            });
        }

        const userMap = new Map(users.map(u => [u.id, u]));
        return raw.map(item => {
            const userId = Number(item.userId);
            const visitCount = Number(item.visitCount);
            const user = userMap.get(userId);
            return {
                userId,
                visitCount,
                nickName: user?.nickName || '未知用户',
                avatarUrl: user?.avatarUrl || '',
            };
        });
    }


    /**
     * 分页查询访问记录
     */
    async page(query: any) {
        const { page = 1, size = 20 } = query;
        const providerId = this.ctx.provider.id;

        const [list, total] = await this.providerVisitLogEntity.findAndCount({
            where: { providerId },
            order: { createTime: 'DESC' },
            take: size,
            skip: (page - 1) * size
        });

        if (list.length === 0) {
            return {
                list: [],
                pagination: {
                    page,
                    size,
                    total
                }
            };
        }

        // 获取用户信息
        const userIds = [...new Set(list.map(e => e.userId))];
        const users = await this.userInfoEntity.find({
            where: { id: In(userIds) },
            select: ['id', 'nickName', 'avatarUrl']
        });

        const userMap = new Map(users.map(u => [u.id, u]));

        const result = list.map(log => {
            const user = userMap.get(log.userId);
            return {
                ...log,
                nickName: user?.nickName || '未知用户',
                avatarUrl: user?.avatarUrl || '',
                visitTime: log.createTime
            };
        });

        return {
            list: result,
            pagination: {
                page,
                size,
                total
            }
        };
    }
}
